from scrabble import *

class ScabbleTest(unittest.TestCase):

    def setUp(self):
        self.myboard = Board()

    def test_read_board_file(self):
        board = Reader.read_board("board.txt")
        self.assertEqual(len(board), 15, "board size not correct")
        self.assertEqual(len(board[14]), 15, "board line size not correct")

    def test_read_move_file(self):
        move = Reader.read_move("move.txt")
        self.assertEqual(len(move), 3, "move size not correct")

    def test_read_dict_file(self):
        dic = Reader.read_dict("SOWPODS.txt")
        self.assertEqual(len(dic), 267751, "Length of dic not correct")
        self.assertEqual(dic.has_key("ABACTERIAL"), True, "Missing word from dictionary")

    def test_validate_array(self):
        dic = Reader.read_dict("SOWPODS.txt")
        self.assertEqual(self.myboard.validate_line(dic, 0, ['.','.'], False), [2,2], "Self.Scrabbleidate failed")
        self.assertEqual(self.myboard.validate_line(dic, 0, ['.','G','.'], False), [2,3,2], "Self.Scrabbleidate failed")
        self.assertEqual(self.myboard.validate_line(dic, 0, ['G','.','.','B','L','E','E','P','.','.','.','.','.','.','Q'], False), [3,2,2,1,1,1,1,1,2,2,2,2,2,2,3], "Self.Scrabbleidate failed")
        board = Reader.read_board("board.txt")        
        self.assertEqual(self.myboard.validate_line(dic, 0, board[0], False), [3,2,2,1,1,1,1,1,2,2,2,2,2,2,3], "Self.Scrabbleidate failed")
        self.assertEqual(self.myboard.validate_line(dic, 1, board[1], False), [3,2,2,3,2,2,2,2,2,2,2,2,3,2,3], "Self.Scrabbleidate failed")

    def test_validate_err_word(self):
        dic = Reader.read_dict("SOWPODS.txt")
        
        self.myboard.validate_line(dic, 0, ['G','.','.','B','L','Q','Q','P','.','.','.','.','.','.','Q'], False)
        word = self.myboard.err_words;
        self.assertEqual(word["0-4"], "BLQQP", "error word not correct")

    def test_validate_no_err_word(self):
        dic = Reader.read_dict("SOWPODS.txt")
        self.myboard.validate_line(dic, 0, ['G','.','.','B','L','E','E','P','.','.','.','.','.','.','Q'], False)
        word = self.myboard.err_words;
        self.assertEqual(word.has_key("0-4"), False, "word should not be error")
      

    def test_flip_array(self):
        board = Reader.read_board("board.txt")
        flip_board = self.myboard.flip_the_board(board)
        self.assertEqual(flip_board[0], ['G', 'I', 'B', 'E', '.', 'O', '.', 'F', 'L', 'A', 'T', 'F', 'I', 'S', 'H'], "flip the board failed")
        flip_back = self.myboard.flip_the_board(flip_board)
        self.assertEqual(flip_back[0],  ['G','.','.','B','L','E','E','P','.','.','.','.','.','.','Q'], "flip the board back failed")

    def test_validate_horizontal_lines(self):
        dic = Reader.read_dict("SOWPODS.txt")
        board = Reader.read_board("board.txt")
        truth_board = self.myboard.validate_horizontal_lines(dic, board, False)
        self.assertEqual(truth_board[1], [3,2,2,3,2,2,2,2,2,2,2,2,3,2,3], "Self.Scrabbleidate failed")
        

    def test_merge_boards(self):
        board = Reader.read_board("board.txt")
        flip_board = self.myboard.flip_the_board(board)

        dic = Reader.read_dict("SOWPODS.txt")
        t_board = self.myboard.validate_horizontal_lines(dic, board, False);
        tflip_board = self.myboard.validate_horizontal_lines(dic, flip_board, True);
        tflip_back = self.myboard.flip_the_board(tflip_board)

        truth_board = self.myboard.merge_boards(t_board, tflip_back)
        self.assertEqual(truth_board[0], [1,2,2,1,1,1,1,1,2,2,2,2,2,2,1], "Self.Scrabbleidate truth board failed")
        

    def test_check_if_board_is_valid(self):
        board = Reader.read_board("board.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        self.assertEqual(self.myboard.check_if_board_is_valid(dic, board), True, "Board is not self.scrabbleid")
    
    def test_bad_start(self):
        invalid_board = Reader.read_board("board_invalid.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        t_board = self.myboard.validate_horizontal_lines(dic, invalid_board, False)
        self.scrabbleid_word = self.myboard.is_bad_start(dic, invalid_board)
        self.assertEqual(self.scrabbleid_word, "BLQQP", "Bad start word not found")

        invalid_ver_board = Reader.read_board("board_invalid_ver.txt")
        word = self.myboard.is_bad_start(dic, invalid_ver_board)
        #print "word: " + word
        self.assertEqual(word, "GQQE", "Bad start word not found")

        invalid_ver_board2 = Reader.read_board("board_invalid_ver2.txt")
        word = self.myboard.is_bad_start(dic, invalid_ver_board2)
        self.assertEqual(word, "GQQE", "Bad start word not found")

    def test_bad_word(self):
        invalid_board = Reader.read_board("board_inv_enter.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        t_board = self.myboard.validate_horizontal_lines(dic, invalid_board, False)
        
        self.scrabbleid_word = self.myboard.is_bad_start(dic, invalid_board)
        self.assertEqual(self.scrabbleid_word, "EQQQR", "Bad start word not found")
        
    def test_no_onechar_word(self):
        board = Reader.read_board("board_invalid.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        t_board = self.myboard.validate_horizontal_lines(dic, board, False)
        for word in self.myboard.err_words:
            #print word +": " + self.myboard.err_words[word] + "Len: " + str(len(self.myboard.err_words[word]))
            self.assertNotEqual(len(self.myboard.err_words[word]), 1, "All single char words are self.scrabbleid")

            
    # test index if flipped e.g. 1-0 & 2-0 = GQQP 
    def test_index_of_flipped(self):
        board = Reader.read_board("board_invalid_ver.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        t_board = self.myboard.get_scrabble_truth_board(dic, board)
        self.assertEqual(self.myboard.err_words["0-0"], "GQQE", "Err word not found")
        self.assertEqual(self.myboard.err_words["1-0"], "GQQE", "Err word not found")
        self.assertEqual(self.myboard.err_words["2-0"], "GQQE", "Err word not found")
        self.assertEqual(self.myboard.err_words["3-0"], "GQQE", "Err word not found")


    def test_convert_move_file(self):
        p = Piece.parse("A2 N")
        self.assertEqual(p.x, 1, "x cooard wrong")
        self.assertEqual(p.y, 0, "y cooard wrong")
        self.assertEqual(p.letter, "N", "letter is wrong")
        move = Reader.read_move("move.txt")
        p = Piece.parse(move[1])
        self.assertEqual(p.x, 2, "x cooard wrong")
        self.assertEqual(p.y, 5, "y cooard wrong")
        self.assertEqual(p.letter, "T", "letter is wrong")

    def test_place_move(self):
        board = Reader.read_board("board.txt")
        move = Reader.read_move("move.txt")
        for line in move:
            p = Piece.parse(line)
            board = self.myboard.play_piece(board, p)
        self.assertEqual(board[1][5], "N", "letter not in correct pos")
        self.assertEqual(board[2][5], "T", "letter not in correct pos")
        self.assertEqual(board[3][5], "E", "letter not in correct pos")

        dic = Reader.read_dict("SOWPODS.txt")
        self.assertEqual(self.myboard.check_if_board_is_valid(dic, board), True, "Board is not self.scrabbleid")

        p = Piece.parse("A2 N")
        board = self.myboard.play_piece(board, p)
        #self.myboard.pretty_print(board)
        self.assertEqual(self.myboard.check_if_board_is_valid(dic, board), False, "Board should not be self.scrabbleid")
        
    
    def test_is_bad_move(self):
        board = Reader.read_board("board.txt")
        dic = Reader.read_dict("SOWPODS.txt")
        self.assertEqual(self.myboard.check_if_board_is_valid(dic, board), True, "Board is not self.scrabbleid")

    def test_adjent(self):
        board = Reader.read_board("board.txt")
        moves = [] 
        moves.append(Piece.parse("B1 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), True, "Should be adjent to one piece")

        moves = [] 
        moves.append(Piece.parse("J2 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), False, "Should not be adjent to any piece")

        moves.append(Piece.parse("J3 A"))
        moves.append(Piece.parse("J4 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), False, "Should not be adjent to any piece")

        moves.append(Piece.parse("J5 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), True, "Should be adjent to one piece")

        #horizontal
        moves = [] 
        moves.append(Piece.parse("K1 A"))
        moves.append(Piece.parse("L1 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), False, "Should not be adjent to any piece")

        moves.append(Piece.parse("M1 A"))
        self.assertEqual(self.myboard.is_adjent(board, moves), True, "Should not be adjent to one piece")


    def test_possible_adjents(self):
        board = Reader.read_board("board.txt")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("B2 A")), [(0, 1), (2, 1), (1, 0), (1, 2)] , "Should be adjent to four pieces")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("A1 A")), [(1, 0), (0, 1)] , "Should be adjent to two pieces")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("O15 A")), [(13, 14), (14, 13)] , "Should be adjent to two pieces")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("A15 A")), [(13, 0), (14, 1)] , "Should be adjent to two pieces")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("O1 A")), [(1, 14), (0, 13)] , "Should be adjent to two pieces")
        self.assertEqual(self.myboard.get_possible_adjents(Piece.parse("O10 A")), [(8, 14), (10, 14), (9, 13)] , "Should be adjent to two pieces")

    def test_overwrite_squares(self):
        board = Reader.read_board("board.txt")
        moves = [] 
        moves.append(Piece.parse("E2 A"))
        moves.append(Piece.parse("C2 A"))
        self.assertEqual(self.myboard.is_no_overwrite(board, moves), True, "Should be no overwritten square for this move")
        
        moves = [] 
        moves.append(Piece.parse("E2 A"))
        moves.append(Piece.parse("C2 A"))
        moves.append(Piece.parse("D2 A"))
        self.assertEqual(self.myboard.is_no_overwrite(board, moves), False, "Should be one overwritten square for this move")

        #vertical
        moves = [] 
        moves.append(Piece.parse("B2 C"))
        moves.append(Piece.parse("B4 C"))
        self.assertEqual(self.myboard.is_no_overwrite(board, moves), True, "Should be no overwritten square for this vertical move")

        moves = [] 
        moves.append(Piece.parse("B2 C"))
        moves.append(Piece.parse("B3 C"))
        self.assertEqual(self.myboard.is_no_overwrite(board, moves), False, "Should be overwritten square for this vertical move")
        
    def test_no_empty_squares(self):
        board = Reader.read_board("board.txt")
        moves = [] 
        moves.append(Piece.parse("E2 A"))
        moves.append(Piece.parse("C2 A"))
        self.assertEqual(self.myboard.is_no_empty_squares(board, moves), True, "Should be no empty squares for this move")
        
        moves = [] 
        moves.append(Piece.parse("E2 B"))
        moves.append(Piece.parse("B2 B"))
        self.assertEqual(self.myboard.is_no_empty_squares(board, moves), False, "Should be empty squares for this move")

        #vertical
        moves = [] 
        moves.append(Piece.parse("B2 C"))
        moves.append(Piece.parse("B4 C"))
        moves.append(Piece.parse("B7 C"))
        self.assertEqual(self.myboard.is_no_empty_squares(board, moves), True, "Should not be empty squares for this vertical move")

        moves = [] 
        moves.append(Piece.parse("B2 C"))
        moves.append(Piece.parse("B7 C"))
        self.assertEqual(self.myboard.is_no_empty_squares(board, moves), False, "Should be empty squares for this vertical move")

    def test_range(self):
        board = Reader.read_board("board.txt")

        #check horizontal
        moves = [] 
        seq = self.myboard.get_sequence_order(moves)
        self.assertEqual(self.myboard.get_row(seq, moves), -1, "no row should be found")
        self.assertEqual(self.myboard.get_range(seq, moves), range(0,0), "range is wrong ... should be 2..5")
        moves.append(Piece.parse("E2 A"))
        seq = self.myboard.get_sequence_order(moves)
        self.assertEqual(self.myboard.get_row(seq, moves), 1, "working with row 1 (2-1)")
        self.assertEqual(self.myboard.get_range(seq, moves), range(4,5), "range is wrong ... should be 4..5")
        moves.append(Piece.parse("D2 A"))
        moves.append(Piece.parse("C2 A"))
        seq = self.myboard.get_sequence_order(moves)
        moves = self.myboard.sort(seq, moves)
        self.assertEqual(self.myboard.get_row(seq, moves), 1, "working with row 1 (2-1)")
        self.assertEqual(self.myboard.get_range(seq, moves), range(2,5), "range is wrong ... should be 2..5")

        #check vertical
        moves = []
        moves.append(Piece.parse("E4 A"))
        moves.append(Piece.parse("E2 A"))
        moves.append(Piece.parse("E8 A"))
        seq = self.myboard.get_sequence_order(moves)
        moves = self.myboard.sort(seq, moves)
        self.assertEqual(self.myboard.get_row(seq, moves), 4, "working with row 1 (E is 4 as A is 0)")
        self.assertEqual(self.myboard.get_range(seq, moves), range(1,8), "range is wrong ... should be 1..8")


    def test_sorting_of_pieces(self):
        board = Reader.read_board("board.txt")
        moves = [] 
        moves.append(Piece.parse("C1 A"))
        moves.append(Piece.parse("I1 A"))
        moves.append(Piece.parse("B1 A"))
        
        seq = self.myboard.get_sequence_order(moves)
        moves = self.myboard.sort(seq, moves)
        self.assertEqual(moves[0].y, 1, "y should be 1")
        self.assertEqual(moves[2].y, 8, "y should be 8")
        
        moves = [] 
        moves.append(Piece.parse("C5 A"))
        moves.append(Piece.parse("C8 A"))
        moves.append(Piece.parse("C3 A"))
        
        seq = self.myboard.get_sequence_order(moves)
        moves = self.myboard.sort(seq, moves)
        self.assertEqual(moves[0].x, 2, "x should be 3")
        self.assertEqual(moves[2].x, 7, "x should be 8")

    #test in seq
    def test_is_move_seq(self):
        moves = [] 
        self.assertEqual(self.myboard.get_sequence_order(moves), CONST.HORIZONTAL, "Zero moves is alway in seqence")

        moves.append(Piece.parse("A1 A"))

        self.assertEqual(self.myboard.get_sequence_order(moves), CONST.HORIZONTAL, "One move is alway in sequence")
        
        moves.append(Piece.parse("A2 B"))
        self.assertEqual(self.myboard.get_sequence_order(moves), CONST.VERTICAL, "Move should be in sequence")

        moves.append(Piece.parse("B2 B"))
        self.assertEqual(self.myboard.get_sequence_order(moves), CONST.INVALID_SEQUENCE, "Move should not be in sequence")

        moves = [] 
        moves.append(Piece.parse("A1 A"))
        moves.append(Piece.parse("B1 S"))
        self.assertEqual(self.myboard.get_sequence_order(moves), CONST.HORIZONTAL, "One move is alway in sequence")

if __name__ == '__main__':
    unittest.main()
